home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / objcissu.lha / runtime-initialization < prev    next >
Internet Message Format  |  1993-03-01  |  21KB

  1. Date: Thu, 19 Nov 92 10:39:44 EST
  2. From: jjobe@mrj.com (jason jobe)
  3. Message-Id: <9211191539.AA05599@mrj.com>
  4. To: gnu-objc@prep.ai.mit.edu
  5. Subject: runtime feature or bug?
  6.  
  7. I just started playing with the gcc 2.3.1 runtime. It seems that if
  8. an "-initialize" method is NOT provided for a new class we crash when running.
  9. I traced it to the fact that a NULL SEL generates an assertion failure. I
  10. changed 3 spots to return NULL if they recieved NULL. Is this a bug or a
  11. feature?
  12.  
  13. I also noticed that the add_record (?) in record.h always increments the 
  14. count even though the comments claim it looks for blank entries to reuse. 
  15. This may or not be responsible for some of the assertion failures (or 
  16. perhaps the hacks mentioned above).
  17.  
  18. Any ideas?
  19.  
  20. Jason
  21. GNU ObjC++
  22.  
  23. Date: Thu, 19 Nov 92 14:23:49 -0500
  24. From: athan@object.com
  25. To: gnu-objc-runtime@prep.ai.mit.edu
  26. Subject: Re: runtime feature or bug?
  27. Cc: jjobe@mrj.com (jason jobe), gnu-objc@prep.ai.mit.edu
  28.  
  29.  
  30. Let's move this discussion over to gnu-objc-runtime.  As you'll notice, I've put that list in the To: line.
  31.  
  32. Regarding a missing method ( + initialize in your case) causing a failure:
  33.  
  34. In general, missing methods should cause forwarding behavior to be triggered.  The Object class should implement a - forward metohd which gets called whenever a selector is sent to an object which does not respond to that selector.  That method can then "do the right thing", for example, it can forward the message on to another object, or, it can signal an error.
  35.  
  36. The default implementation would probably look something like:
  37.  
  38. - forward:(SEL)aSelector <whatever other gnu-runtime parameters are relevant>
  39. {
  40.   return [self doesNotImplement:aSelector <...>];
  41. }
  42.  
  43. where doesNotImplement is also implemented by Object and might printf() a message or something like that.
  44.  
  45. This, btw, is taken largely from the NeXT and Smalltalk regimes.
  46.  
  47. Andrew Athan
  48. Objective Technologies, Inc.
  49.  
  50. From: ssircar@canon.com (Subrata Sircar)
  51. Date: Thu, 10 Sep 92 14:13:02 PDT
  52. To: athan@object.com (Andrew C . Athan)
  53. Subject: Re: NeXT objc extentions (Was: Your mission, should you choose to accept it. . .)
  54. Cc: ObjC@canon.com
  55.  
  56. I wrote:
  57. >Question:  what happens if you declare x to be "SomeControllerClass
  58. >*"?  If the warning goes away then, I would be happier, since now
  59. >you have told it what object x points to.
  60. >[More generally, the compiler won't complain if you say id x =
  61. >anObject; [x someMethod];.  This is generally held to be a good
  62. >thing for polymorphism.  Do we want the same thing for protocols?]
  63.  
  64. athan@object.com (Andrew C . Athan) wrote:
  65. ! Neither one of these solves the problem.  SomeControllerClass *x
  66. ! declares x to be a pointer to an instance of SomeControllerClass.
  67. ! What if x is pointing to a class object? i.e.
  68. ! x=[SomeControllerClass class];
  69.  
  70. Hmmm.  Good question.  What should happen?  Should the compiler type-check and allow x to only respond to class messages?  What is the declaration of x in this case?
  71.  
  72. > Actually, this also makes sense to me.  The general question is:
  73. > given an interface declaration, where should the implementation be?
  74. > If you choose to allow it to be split up, then the compiler must
  75. > not issue warnings when compiling the file, but must check back
  76. > after all the files are compiled (in case the missing code has been
  77. > added in a different file).  NeXT essentially passed the buck on
  78. > this question and required it to be in a single file.
  79.  
  80. ! I was not clear.  What you say is true, and I think it is reasonable not to
  81. ! do this sort of meta checking.  However, there is no reason to get warnings
  82. ! when all the categories implementing all the protocol methods are in the
  83. ! same .m.  That is the behavior I disliked.  E.g.:
  84. [Example deleted]
  85.  
  86. For clarity, the multiple implementations in a single file make sense.  It should make code more readable, which is always a laudable goal :<)
  87.  
  88. However, doesn't that put us into the same situation?  If the compiler doesn't find an method in the base implementation, what should it do?
  89. Should it
  90. a) flag an error
  91. b) finish the current file and then check
  92. c) finish the compile stage and then check
  93.  
  94. Currently, NeXT does a).  I can make a case for c) but I'm not sure about b).
  95.  
  96. > However, for a given protocol which you write (and hence might be
  97. > changed - I'm not terribly worried about the system protocols
  98. > changing) you can add a version number method to the protocol, and
  99. > require that implementers return the protocol version number as
  100. > given in the header.
  101.  
  102. ! This is an adequate solution, but it is not (IMHO) necessarily the nicest.
  103. ! Also, it does not address the problem that I can get a true return from
  104. ! conformsTo: and the class actually does not conformTo:!
  105.  
  106. I agree.  Version control over protocols would be a good feature to add to the GNU Objective-C version of protocols, since we're still in the design stage.
  107.  
  108. - Subrata Sircar
  109. ssircar@canon.com        Canon Information Systems
  110.  
  111. Date: Thu, 10 Sep 92 17:07:41 -0500
  112. From: jr@alpo.media.com (J.R. Jesson)
  113. To: gnu-objc@prep.ai.mit.edu
  114. Subject: Re: NeXT objc extentions (Was: Your mission, should you choose to accept it. . .)
  115.  
  116. Andrew Athan (athan@object.com) writes:
  117.  
  118. > [Previous discussion about @class, @protocol, etc.]
  119. >
  120. > There are other issues besides whether or not the
  121. > compiler code will become available from NeXT.  I
  122. > personally feel that the @protocol extension has not
  123. > been completely thought out by NeXT;  I don't claim to know
  124. > everything about it yet, nor do I claim to be doing
  125. > everything right, but I feel certain pieces are
  126. > missing/broken/not well thought out.
  127. >
  128. > To elaborate:  Though I can only guess, I'd say that NeXT
  129. > put in @protocol largely as support for their
  130. > distributed objects paradigm (so an NXProxy can say,
  131. > conformsTo:@protocol(SOMETHING) instead of
  132. > isKindOf:[Something class]) .. much like they added
  133. > keywords like "out," "in," and "inout."  An @protocol
  134. > (sometimes) builds a structure describing the methods;
  135. > that structure is then tacked on to the Class object and
  136. > can be used at runtime w/ distributed objects.  This is all
  137. > fine, as far as distributed objects go.
  138.  
  139. I think that NeXT put the protocol stuff for a couple of reasons.
  140. First, it eliminates round-trips through the "wire" to do selector
  141. validation and error reporting. I found this explanation in the NeXTSTEP PR2 release notes (DistributedObjects.rtf):
  142.  
  143. "...A client may specify the expected Protocol that an object will
  144. serve upon the completion of a connection.  Providing this
  145. specification enables more efficient delivery of messages to remote
  146. objects by avoiding a "discovery" message per method..."
  147.  
  148. It makes a big difference in the efficiency of sending
  149. methods and the data associated with it across the wire. Ask any X
  150. programmer about the evils of round trips to the X server.  (Or ask a
  151. naive X programmer why their apps run slowly - it could be because
  152. they dont understand about server trips ;-) ).
  153.  
  154. I like protocols better than categories for doing things like
  155. insuring that I've got all the methods needed to support delegate
  156. operations.  Again using NeXTSTEP as an example, my View classes
  157. which do drag & drop declare the protocol <NXDraggingInfo> in the
  158. @implementation directive.  The compiler enforces the type and
  159. existence of those methods without requiring that I put them
  160. in an @interface clause of a superclass of the object I'm defining.
  161. Again from the NeXT Literature (misspellings complements of NeXT):
  162.  
  163. "Protocols allow you to organize related method into groups that form
  164. high-level behaviors. This gives library builders a tool to identifiy
  165. sets of standard protocols, independent of the class hierarchy.
  166. Protocols provide language support for the reuse of design (i.e.
  167. interface), whereas classes support the reuse of code (i.e.
  168. implementation). Well designed protocols can help users of an
  169. application framework when learning or designing new classes."
  170.  
  171. [ Good complaints about protocols deleted... ]
  172.  
  173. > An additional problem that I see with @protocol is the
  174. > question of versioning.  Protocol checking is to some
  175. > degree a compile-time event (and therefore versioning
  176. > is not as important).  @protocol is, however, often used
  177. > as a run-time tool: it is possible to ask an object if it
  178. > conforms to a protocol.  Currently, I cannot attach a
  179. > version number to a protocol.  Because of this, if someone
  180. > writes and compiles an object given the Controllers
  181. > protocol above, and I then at a later time write code which
  182. > does:
  183. >
  184. > if([someController
  185. > conformsTo:@protocol(Controllers)])
  186. >
  187. > in the meantime, having changed the Controllers
  188. > protocol, I am in trouble. 
  189.  
  190. Yeah.  I hadn't thought this issue through before now, but this
  191. seems to be a lacking of the @protocol directive.  Interestingly,
  192. if you look at the file <objc/Protocol.h> you will find that
  193. protocols are objects which are subclasses of the root object class:
  194.  
  195. @interface Protocol : Object
  196. {
  197. @private
  198. [ private stuff deleted ]
  199. }
  200. @end
  201.  
  202. So, in the NeXT environment, it ought to be possible to attach a version number to the protocol using the NeXT factory method:
  203.  
  204. [ {aClass} setVersion: {anInt} ];
  205.  
  206. Of course the trick is finding the handle to the protocol "object".
  207. Since versioning is only important when protocols are used in
  208. distributed object messaging, what ought to happen is the proxy
  209. object do a version validation when the connection is established
  210. to a servicing process.  Since this issue is a run-time support issue, and not a compilation issue, it seems sensible to say that @protocols
  211. are Ok in concept but need help in implementation.
  212.  
  213. So, how does this discussion relate to gnu Objective-C?  I think
  214. we ought to improve protocols so that:
  215.  
  216. (1) we can find the handle to the protocol ( i.e. [ <protocolName> class ]
  217. (2) the runtime is augmented so that version checking is
  218. done.
  219.  
  220. jr
  221.  
  222. ---
  223. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  224. J.R. Jesson
  225. Chief Development Dude, All-Around Nice Guy, Wirehead
  226. Multimedia Learning, Inc.
  227. (214)869-8282
  228. jr@media.com
  229. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  230.  
  231. Date: Fri, 12 Feb 1993 04:04:26 +0100
  232. From: Kresten Krab Thorup <krab@iesd.auc.dk>
  233. To: mu@pcsbst.pcs.com, gnu-objc-submissions@gnu.ai.mit.edu
  234. Subject: ObjC library
  235.  
  236. I have found two problems.
  237.  
  238. 1: Making sure +initialize of class NIL is called -- this is serious,
  239.    as the tuntime depends on it.... how do you do that?  The problem
  240.    is, that NIL is independant from the rest of the hieracy, and 
  241.    the current execClass may actually do the initialization part
  242.    before it has recieved a call for class NIL!!!
  243.  
  244. 2: If a +initialize function invokes other objects, which class has
  245.    not yet been initialized, you get a bad assertion in msgSend.
  246.    I suggest making objc_msgSend a pointer to a function, and using
  247.    the one with check for initialization during the loop which
  248.    initializes the classes, and another fast version after that.
  249.  
  250. Major problem: How do we know if all classes have been processed in
  251. objc_execClass? It may be, that the final class is `independant' --
  252. i.e. does not inherit class Object, but that the +initialize of other
  253. classes uses its features??? What can we do?
  254.  
  255. /Kresten
  256.  
  257. PS:  I was actually close to release a collection library of my own,
  258. very much like yours, so I have quite a few comments -- I will,
  259. however, start on from your code, and make the best out of it... Some
  260. of the algorithms e.g. those in Set can be done alot better.
  261.  
  262.  
  263. Return-Path: <krab@iesd.auc.dk>
  264. Date: Wed, 17 Feb 1993 01:19:29 +0100
  265. From: Kresten Krab Thorup <krab@iesd.auc.dk>
  266. To: rms@gnu.ai.mit.edu, gsk@marble.com
  267. Subject: gnu objc runtime
  268.  
  269. [...moved...handling of messages to nil...]
  270.  
  271. For the matter of initialization, I have done the following changes:
  272.  
  273. Changed __main by supplying it directly in the library, so that it
  274. first calls __objc_initExecClass, then do_global_ctors (which in term
  275. calls __objc_execClass for each module), and finally it calls
  276. __objc_doneExecClass.  This allows me to get complete control of the
  277. initialization.
  278.  
  279. __objc_initExecClass sets up a special version of objc_msgSend, which
  280. is needed when sending messages from +initialize methods, because the
  281. receiver may not itself be initialized by then.  It also allocates
  282. tables for assembling information in the next phase.
  283.  
  284. __objc_execClass collects diverse information on modules, classes and
  285. selectors etc.  Currently it does do some resolving, but it is more
  286. efficient to wait until after all modules have been studied.
  287.  
  288. __objc_doneExecClass calls initialize_dispatchtables (described below)
  289. and calls +initialize for all classes.  (This is where the special
  290. version of the messenger is needed.)  Finally, it installs the
  291. `default' (fast) version of the messenger and returns control (to
  292. main).
  293.  
  294. initialize_dispatchtables installs IMP's for each selector/class pair,
  295. as collected from the modules, but for all non-existent such pairs, it
  296. installs the special function undefined_method which takes care of
  297. calling doesNotRecognize etc.
  298.  
  299. The messenger stuff means, that objc_sendMsg really calls via a
  300. function pointer, which is very handy also if the programmer for
  301. instance wants to define his own anyway. This should be changed in
  302. gcc, so that I dont have to define a `dummy' messenger just for
  303. forwarding.  We cannot avoid having the messenger to check for
  304. initialized classes at least during the initialization phase, so it
  305. will only speed up to have two versions.
  306.  
  307. I am a little in doubt, if it is `allowed' to change __main like I do.
  308. My current implementation will only work if collect is used, so
  309. something will have to be incorporated into gnu-ld (correct?)
  310.  
  311. So what does need to be done?  In general, the initialization phase
  312. could be much faster, and the current implementation of method lookup
  313. is a bit expensive (in space, not time).  Does other runtimes store the
  314. methods in an class/selector array?  All calls to libc should be
  315. avoided, or somehow encapsulated in dispatch vectors, so that they may
  316. be controlled by the environment.  I am working on forwarding of
  317. messages, but it will only be able to return id's until you (Stallman)
  318. fix up some construct for that.  The structures for storing internal
  319. data could be optimized a lot.
  320.  
  321. For the runtime system to be complete, it must have an additional
  322. number of `system' classes like files/streams.  What should be the
  323. guidelines in defining such?  Should we blindly use something close to
  324. what NeXT does, or is it ok to come up with a new design perhaps
  325. inspired by C++ or Smalltalk streams?  How far can I/we go -- what is
  326. the goal?
  327.  
  328. For the sake of the experiment I have made a WEB for objc.  Do you
  329. dislike WEB?  The runtime is rather compact and complicated, so it
  330. would be ideal for being described in WEB.
  331.  
  332. I would appreciate comments on all issues!
  333.  
  334. /Kresten
  335.  
  336. Return-Path: <krab@iesd.auc.dk>
  337. Date: Wed, 17 Feb 1993 14:16:48 +0100
  338. From: Kresten Krab Thorup <krab@iesd.auc.dk>
  339. To: gsk@marble.com
  340. Subject: gnu objc runtime (initialization)
  341.  
  342. I will explain to you why we need some more control in the
  343. initialization phase.  The simplest possible case, where the current
  344. scheme may fail is like this:
  345.  
  346.   There exists classes A and B.  Both inherit Object.  Now, if A
  347.   implements an +initialize like this:
  348.  
  349.     +initialize
  350.     {
  351.       someGlobalVar = [B new];
  352.     }
  353.  
  354.   Some time during initialization (n'th call of execClass)  we
  355.   determine, that it is time to call that initializer of class A.  
  356.   This can fail for several reasons: B may not be initialized, which
  357.   means, that B is in an unsafe state.  B may not have been seen, in
  358.   which case the selectors `over there' are unknown.  Or finnaly the
  359.   same problems may apply recursively to anything B depends on (If
  360.   there were more classes in the system)
  361.  
  362. So how can we determine if it is safe to initialize class A?  The
  363. current scheme tries to `guess' if it is safe by not calling
  364. +initialize of class A, if any unresolved superclasses exists, but
  365. that will be the case (and fail) if we have only seen class Object and
  366. class A so far.  Since (I guess) we dont want to store a full
  367. dependancy hieracy each module, we will at least have to make
  368. `do_global_ctors' or whatever tell us if all classes have been seen.
  369. That is what I used __objc_doneExecClass for.
  370.  
  371. Next, once we know that all classes have been seen, we still have to
  372. make sure, that class B is initialized before it is called in the
  373. above example.  For this reason, we have to use a make objc_msgSend
  374. check if the reciever has been initialized, an if not, than do so.
  375. But this check is only needed during the initialization phase, and
  376. hence I made two messengers, and used a pointer to a function to call
  377. either. 
  378.  
  379. The problems cannot be solved by calling +inititialize in some fancy
  380. order, since class B may depend on class A being initialized to (some
  381. extend).  We have to check for initialization in the messenger as far
  382. as I can see.
  383.  
  384. If we can accept, that cyclic dependencies in +initialize'ers is not
  385. allowed, we may be able to solve the problems, by having gcc produce a
  386. list of all needed classes for each +initialize method, or perhaps we
  387. could simply use a special messenger inside that method.  I have not
  388. thought this through, and I'm not sure if it suffices.
  389.  
  390. /Kresten
  391.  
  392. Return-Path: <krab@iesd.auc.dk>
  393. Date: Sat, 20 Feb 1993 21:31:33 +0100
  394. From: Kresten Krab Thorup <krab@iesd.auc.dk>
  395. To: burchard@geom.umn.edu
  396. Cc: Kresten Krab Thorup <krab@iesd.auc.dk>, gnu-objc@gnu.ai.mit.edu
  397. In-Reply-To: <9302202004.AA03247@localhost.gw.umn.edu>
  398. Subject: Re: Optimizing the GNU objc runtime
  399.  
  400. Paul Burchard writes:
  401. >My only question would be how much time a "typical" program would
  402. >spend at startup, filling all the dispatch caches. Would the wait be
  403. >noticeable on a human timescale?  (If you have ~100 classes with ~100
  404. >methods each, and you want to keep extra startup overhead to no more
  405. >than 1/20 second, that only allows you 5 ms per lookup.)
  406.  
  407. A system of this scale (100 classes is quite a lot) would typically be
  408. running for more than just a moment.  The accurate time used for
  409. building this table will of course differ on different platforms, but
  410. we are only talking about traversing 10k words in this case.  Besides,
  411. the time you would use for building a dispatch table based on hashing
  412. would presumably not be faster, only save space.
  413.  
  414. A note in this context:  The currently distributed runtime may happen
  415. to allocate and initialize the dispatch tables multiple times, thus
  416. you should not base any judgement on the basis of the current system.
  417.  
  418. /Kresten
  419.  
  420. Kresten Krab Thorup               |       /   | E-mail : krab@iesd.auc.dk
  421. Institute of Electronic Systems   |   ,-'/(   | S-mail : Sigrid Undsetsvej 226A
  422. Aalborg University                |  /  |  \  |          9220 Aalborg \O
  423. Fr. Bajers vej 7, DK-9220 Aalb    |  A  U  C  |          Denmark
  424. -------------------------------------------------------------------------------
  425.                Member of The League for Programming Freedom
  426.  
  427. Return-Path: <burchard@localhost.gw.umn.edu>
  428. Date: Sun, 21 Feb 93 16:24:26 -0600
  429. From: Paul Burchard <burchard@localhost.gw.umn.edu>
  430. To: Kresten Krab Thorup <krab@iesd.auc.dk>
  431. Subject: Re: Optimizing the GNU objc runtime
  432. Cc: gnu-objc@gnu.ai.mit.edu
  433. Reply-To: burchard@geom.umn.edu
  434.  
  435. Kresten Krab Thorup <krab@iesd.auc.dk> writes:
  436. > A system of this scale (100 classes is quite a lot) would
  437. > typically be running for more than just a moment.
  438.  
  439. Let me first say that I'm very interested in trying out your more  
  440. efficient run time...I think it's great that you're doing this.
  441.  
  442. It should be said, though, that 100 different selectors by 100  
  443. classes may actually be a low estimate for perfectly reasonable  
  444. programs.  NeXT's AppKit, for example, has (roughly) 2000 different  
  445. selectors and 70 classes.  Even if just the *top-level* classes were  
  446. used in a program, that would mean looking up 140,000 implementations  
  447. at startup.
  448.  
  449. > I have received numerous comments on `is this the right
  450. > way to do message lookup?' i.e. using a simple array for
  451. > dispatch is too expensive in the long run. 
  452.  
  453.  
  454. Long run?  The only long run cost is memory, not time.  Well, I guess  
  455. memory can turn into some serious time if you use too much of it and  
  456. get swapped out....in the above example we would pay a 0.5 MB memory  
  457. price per program (assuming 32-bit addresses).
  458.  
  459. Besides startup time and memory usage, the only other possible  
  460. stumbling block I can see is thread safety.  Those concerned with  
  461. thread safety, however, may be willing to forgo these efficiencies  
  462. and use the standard runtime, since the non-threaded alternative  
  463. (remote messaging between different processes which use the efficient  
  464. runtime) is probably more expensive.
  465.  
  466. --------------------------------------------------------------------
  467. Paul Burchard    <burchard@geom.umn.edu>
  468. ``I'm still learning how to count backwards from infinity...''
  469. --------------------------------------------------------------------
  470.  
  471.